package org.nimi317.web_gis.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.nimi317.web_gis.exception.E;
import org.nimi317.web_gis.exception.RException;
import org.nimi317.web_gis.dao.RoleMapper;
import org.nimi317.web_gis.entity.RP;
import org.nimi317.web_gis.entity.Role;
import org.nimi317.web_gis.entity.UR;
import org.nimi317.web_gis.service.IRPService;
import org.nimi317.web_gis.service.IRoleService;
import org.nimi317.web_gis.service.IURService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author nimi317
 * @since 2024-04-13
 */
@Service
@Transactional
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    private final IURService urService;

    private final IRPService irpService;

    public RoleServiceImpl(IURService urService, IRPService irpService) {
        this.urService = urService;
        this.irpService = irpService;
    }

    @Override
    public void createRole(Role role) {
        extracted(role);
        this.save(role);
    }

    private void extracted(Role role) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRName, role.getRName());
        boolean exists = this.exists(wrapper);
        if (exists) {
            throw new RException(E.RoleNameException);
        }
    }

    @Override
    public void deleteRole(Integer roleId) {
        //删除角色
        boolean b = this.removeById(roleId);

        //删除用户角色关联
        LambdaQueryWrapper<UR> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UR::getR, roleId);
        boolean remove = urService.remove(wrapper);

        LambdaQueryWrapper<RP> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RP::getR, roleId);
        boolean removed = irpService.remove(queryWrapper);
        if (!b || !remove || !removed) {
            throw new RException(E.DeleteRoleException);
        }
    }

    @Override
    public void updateRole(Role role) {
        extracted(role);
        this.updateById(role);
    }

    @Override
    public List<Role> getAllRoles() {
        return this.list();
    }

    @Override
    public List<String> getRolesByUserId(Integer userId) {

        //从ur列表中获取所有roles 的id
        LambdaQueryWrapper<UR> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(UR::getR)
                .eq(UR::getU, userId);
        List<Integer> list = urService.list(wrapper).stream().map(UR::getR).toList();
        if (ObjectUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        //根据id查询
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Role::getId, list);
        return this.list(queryWrapper).stream().map(Role::getRName).toList();
    }

    @Override
    public void associateRole(Integer userId, List<Integer> roleIds) {
        HashSet<Integer> integers = new HashSet<>(roleIds);

        //搜索是否所有roleId都存在
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Role::getId, roleIds);
        long count = this.count(wrapper);
        if (count != integers.size()) {
            throw new RException(E.UserRoleException);
        }

        //删除所有原有的角色
        LambdaQueryWrapper<UR> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UR::getU, userId);
        urService.remove(queryWrapper);

        if (ObjectUtils.isEmpty(integers)) {
            return;
        }

        //添加新的角色
        List<UR> urs = roleIds.stream().map(item -> new UR(userId, item)).toList();
        urService.saveBatch(urs);
    }
}
